package hotel.meituan.oversea.biz.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.enums.MtHotelEnums;
import hotel.base.oversea.dto.meituan.MtHotelRoomDto;
import hotel.base.oversea.service.impl.BaseServiceImpl;
import hotel.base.oversea.utils.GsonUtils;
import hotel.base.oversea.utils.Result;
import hotel.base.oversea.vo.MtRoomInfoReturnVo;
import hotel.base.oversea.vo.meituan.request.room.MtHotelRealRoomBaseInfoVo;
import hotel.base.oversea.vo.meituan.request.room.MtHotelRealRoomVo;
import hotel.base.oversea.vo.meituan.request.room.MtHotelRoomVo;
import hotel.base.oversea.vo.meituan.response.goods.MtHotelGoodsBaseRoomVo;
import hotel.meituan.oversea.api.vo.up.response.hotel.MtHotelDetailBasicRoomRealInfoVo;
import hotel.meituan.oversea.api.vo.up.response.hotel.MtHotelDetailRoomInfoVo;
import hotel.meituan.oversea.api.vo.up.response.hotel.MtHotelDetailVo;
import hotel.meituan.oversea.biz.service.MtHotelRoomNameService;
import hotel.meituan.oversea.biz.service.MtHotelRoomService;
import hotel.meituan.oversea.biz.service.MtHotelService;
import hotel.meituan.oversea.biz.utils.MtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class MtHotelRoomNameServiceImpl extends BaseServiceImpl implements MtHotelRoomNameService {
    @Resource
    private MtHotelRoomService mtHotelRoomService;

    @Resource
    private MtHotelService mtHotelService;

    @Override
    public String getRoomNameByGoodsIdHotelId(List<MtHotelRealRoomVo> oneHotelRoomInfos,String hotelId,List<MtHotelGoodsBaseRoomVo> goodsBaseRoom,String goodsId){//List<MtHotelGoodsBaseRoomVo> goodsBaseRoom  产品的房型信息 size=1  可能逻辑或者物理 需要再次判断
        log.info("getRoomNameByGoodsIdHotelId 校验 hotelId={},goodsBaseRoom={}",hotelId,GsonUtils.GsonString(goodsBaseRoom));
        String roomName = null;
        if(null != goodsBaseRoom && goodsBaseRoom.size()>0){
            MtHotelDetailVo hotelDetail = returnHotelDetailRoomListByOneHotelId(hotelId);
            MtRoomInfoReturnVo mtRoomInfoReturnVo =  this.goodsInfosCheckReturnGoodsRealRoomIdAndName(oneHotelRoomInfos,hotelDetail,hotelId,goodsBaseRoom,goodsId);
            if(!ObjectUtils.isEmpty(mtRoomInfoReturnVo) && null != mtRoomInfoReturnVo.getRealRoomId()){
                if(null != mtRoomInfoReturnVo.getRoomName()){
                    roomName = mtRoomInfoReturnVo.getRoomName();
                }else{
                    Result r = mtHotelRoomService.getMtHotelRoomById(hotelId,mtRoomInfoReturnVo.getRealRoomId());
                    log.info("getRoomNameByGoodsIdHotelId 校验 获取到真实房型id getMtHotelRoomById={}",GsonUtils.GsonString(r));
                    if(r.getCode()==CommonConstants.SUCCESS){
                        MtHotelRoomDto mtHotelRoomDto = (MtHotelRoomDto)r.getData();
                        if(null != mtHotelRoomDto){
                            roomName = mtHotelRoomDto.getMtRoomName();
                        }
                    }
                }

            }
        }
        log.info("getRoomNameByGoodsIdHotelId 校验 返回房型名称 roomName={}",roomName);
        return roomName;
    }

    /**
     * 获取产品所属真实物理房型id （参数 酒店详情接口物理房型信息，美团酒店id，Rp接口产品room信息，产品id）
     * --》外部查询一次酒店详情接口，，内部涉及查询一次物理房型接口
     * @param voList
     * @param thisMtHotelId
     * @param goodsBaseRoom
     * @param goodsId
     * @return
     */
 /*   @Override
    public String goodsInfosCheckReturnGoodsRealRoomIdxxxx(List<MtHotelDetailVo> voList,String thisMtHotelId,List<MtHotelGoodsBaseRoomVo> goodsBaseRoom,String goodsId){
        String goodsApiReturnRoomIdFalse = goodsBaseRoom.get(0).getRoomId();
        String goodsApiReturnRoomIdTrue = goodsBaseRoom.get(0).getRealRoomId();
        //方案一校验（45%）
        String returnRealRoomId = findRealRoomIdByGoodsRealRoomIdNotNull(voList,thisMtHotelId,goodsBaseRoom);
        if(ObjectUtils.isEmpty(returnRealRoomId)){//方案一 未获取到真实物理房型id
            if(null == goodsApiReturnRoomIdTrue && null != goodsApiReturnRoomIdFalse){//产品接口的realid为空falseid不为空
                //方案二校验（5%）
                MtRoomInfoReturnVo thisReturnVo = findRealRoomIdByGoodsIdRealIsNull(thisMtHotelId,goodsId);//涉及查询物理房型接口
                if(null != thisReturnVo){
                    returnRealRoomId = thisReturnVo.getRealRoomId();
                }
                if(ObjectUtils.isEmpty(returnRealRoomId)){
                    //第三方案校验（50%）
                    returnRealRoomId = findRealRoomIdByGoodsFalseRoomIdRealIsNull(voList,thisMtHotelId,goodsBaseRoom);
                }
            }
        }
        return returnRealRoomId;
    }*/
    /**
     * 获取产品所属真实物理房型id （参数 酒店详情接口物理房型信息，美团酒店id，Rp接口产品room信息，产品id）
     * --》外部查询一次酒店详情接口，，内部涉及查询一次物理房型接口
     * @param hotelDetail
     * @param thisMtHotelId
     * @param goodsBaseRoom
     * @param goodsId
     * @return
     */
    @Override
    public String goodsInfosCheckReturnGoodsRealRoomId(List<MtHotelRealRoomVo> oneHotelRoomInfos, MtHotelDetailVo hotelDetail, String thisMtHotelId, List<MtHotelGoodsBaseRoomVo> goodsBaseRoom, String goodsId){
        String goodsApiReturnRoomIdFalse = goodsBaseRoom.get(0).getRoomId();
        String goodsApiReturnRoomIdTrue = goodsBaseRoom.get(0).getRealRoomId();
        //方案一校验（45%）
        String returnRealRoomId = findRealRoomIdByGoodsRealRoomIdNotNull(hotelDetail,thisMtHotelId,goodsBaseRoom);
        if(ObjectUtils.isEmpty(returnRealRoomId)){//方案一 未获取到真实物理房型id
            if(null == goodsApiReturnRoomIdTrue && null != goodsApiReturnRoomIdFalse){//产品接口的realid为空falseid不为空
                //方案二校验（5%）
                MtRoomInfoReturnVo thisReturnVo = findRealRoomIdByGoodsIdRealIsNull(oneHotelRoomInfos,thisMtHotelId,goodsId);//涉及查询物理房型接口
                if(null != thisReturnVo){
                    returnRealRoomId = thisReturnVo.getRealRoomId();
                }
                if(ObjectUtils.isEmpty(returnRealRoomId)){
                    //第三方案校验（50%）
                    returnRealRoomId = findRealRoomIdByGoodsFalseRoomIdRealIsNull(hotelDetail,thisMtHotelId,goodsBaseRoom);
                }
            }
        }
        return returnRealRoomId;
    }
    @Override
    public MtRoomInfoReturnVo goodsInfosCheckReturnGoodsRealRoomIdAndName(List<MtHotelRealRoomVo> oneHotelRoomInfos, MtHotelDetailVo hotelDetailVo, String thisMtHotelId, List<MtHotelGoodsBaseRoomVo> goodsBaseRoom, String goodsId){
        String goodsApiReturnRoomIdFalse = goodsBaseRoom.get(0).getRoomId();
        String goodsApiReturnRoomIdTrue = goodsBaseRoom.get(0).getRealRoomId();
        MtRoomInfoReturnVo thisReturnVo = new MtRoomInfoReturnVo();
        //方案一校验（45%）
        Map<String,String> map = new HashMap<>();
        String returnRealRoomId = findRealRoomIdByGoodsRealRoomIdNotNull(hotelDetailVo,thisMtHotelId,goodsBaseRoom);
        if(ObjectUtils.isEmpty(returnRealRoomId)){//方案一 未获取到真实物理房型id
            if(null == goodsApiReturnRoomIdTrue && null != goodsApiReturnRoomIdFalse){//产品接口的realid为空falseid不为空
                //方案二校验（5%）
                thisReturnVo = findRealRoomIdByGoodsIdRealIsNull(oneHotelRoomInfos,thisMtHotelId,goodsId);//涉及查询物理房型接口
                if(null != thisReturnVo){
                    returnRealRoomId = thisReturnVo.getRealRoomId();
                }
                if(ObjectUtils.isEmpty(returnRealRoomId)){
                    //第三方案校验（50%）
                    returnRealRoomId = findRealRoomIdByGoodsFalseRoomIdRealIsNull(hotelDetailVo,thisMtHotelId,goodsBaseRoom);
                    thisReturnVo.setRealRoomId(returnRealRoomId);
                }
            }
        }
        return thisReturnVo;
    }

    /**
     * 方案1.产品接口 产品realRoomid不为空，则直接查询酒店详情接口的物理房型信息匹配（35%）
     */
    @Override
    public String findRealRoomIdByGoodsRealRoomIdNotNull(MtHotelDetailVo vo, String thisMtHotelId, List<MtHotelGoodsBaseRoomVo> goodsBaseRoom){
        //String goodsApiReturnRoomIdFalse = goodsBaseRoom.get(0).getRoomId();
        String goodsApiReturnRoomIdTrue = goodsBaseRoom.get(0).getRealRoomId();//方案一 校验产品的
        String returnRealRoomId = null;
        if(!ObjectUtils.isEmpty(goodsApiReturnRoomIdTrue)){
            List<MtHotelDetailRoomInfoVo> roomRealVoList = vo.getRoomInfos();
            if(null != roomRealVoList && roomRealVoList.size()>0) {
                for (MtHotelDetailRoomInfoVo roomInfoVo : roomRealVoList) {
                    MtHotelDetailBasicRoomRealInfoVo realVo = roomInfoVo.getRoomBaseInfo();
                    String thisHotelDetailVoFalseRoomId = realVo.getRoomId();//酒店详情接口返回假的roomId
                    String thisHotelDetailVoTrueRoomId = realVo.getRealRoomId();//酒店详情接口返回真的roomId
                    if(goodsApiReturnRoomIdTrue.equals(thisHotelDetailVoFalseRoomId) || goodsApiReturnRoomIdTrue.equals(thisHotelDetailVoTrueRoomId)){
                        returnRealRoomId = thisHotelDetailVoTrueRoomId;
                        break;
                    }
                }
                log.info("findRealRoomIdByGoodsRealRoomIdNotNull获取酒店真实房型酒店id={},realidlist={}，goodsBaseRoom={}",thisMtHotelId,GsonUtils.GsonString(roomRealVoList),GsonUtils.GsonString(goodsBaseRoom));
            }
            if(ObjectUtils.isEmpty(returnRealRoomId)){
                log.info("findRealRoomIdByGoodsRealRoomIdNotNull获取酒店真实房型酒店id={},result={},thisRealRoomId={}，goodsBaseRoom={}",thisMtHotelId,GsonUtils.GsonString(vo),returnRealRoomId,GsonUtils.GsonString(goodsBaseRoom));
            }else{
                log.info("findRealRoomIdByGoodsRealRoomIdNotNull获取酒店真实房型酒店id={},thisRealRoomId={}，goodsBaseRoom={}",thisMtHotelId,returnRealRoomId,GsonUtils.GsonString(goodsBaseRoom));
            }
        }
        return returnRealRoomId;

    }
    /**
     * 方案2.产品接口 产品realRoomid为空，先比对物理房型接口的goodsids是否可匹配到该产品再得到对应roomid（5%）（少部分是这种情况）
     */
    @Override
    public MtRoomInfoReturnVo findRealRoomIdByGoodsIdRealIsNull(List<MtHotelRealRoomVo> oneHotelRoomInfos,String mtHotelId,String goodsId){
        String returnRealRoomId = null;
        String returnRoomName = null;
        List<Long> hotelIds = new ArrayList<>();
        hotelIds.add(Long.valueOf(mtHotelId));
       /* Result result = mtHotelRoomService.getMtHotelRoom(hotelIds);
        if(result.getCode()==CommonConstants.SUCCESS){
            //List<MtHotelRealRoomVo> oneHotelRoomInfos = (Map<Long, List<MtHotelRealRoomVo>>)result.getData();

        }*/
        if(null != oneHotelRoomInfos && oneHotelRoomInfos.size()>0){
            //List<MtHotelRealRoomVo> oneHotelRoomInfos = oneHotelRoomInfos.get(Long.valueOf(mtHotelId));
            if(null != oneHotelRoomInfos && oneHotelRoomInfos.size()>0){
                for (MtHotelRealRoomVo oneRoomInfo:oneHotelRoomInfos){
                    List<Integer> goodsIds = oneRoomInfo.getGoodsIds();
                    if(null != goodsIds && goodsIds.size()>0){
                        for (Integer id:goodsIds){
                            if(new BigDecimal(id).compareTo(new BigDecimal(goodsId))==0){
                                MtHotelRealRoomBaseInfoVo baseRoom = oneRoomInfo.getRealRoomBaseInfo();
                                if(null != baseRoom){
                                    Integer realRomId = baseRoom.getRealRoomId();
                                    String realRoomName = baseRoom.getRoomName();
                                    if(null != realRomId){
                                        returnRealRoomId = String.valueOf(realRomId);
                                        returnRoomName = realRoomName;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        MtRoomInfoReturnVo mtRoomInfoReturnVo = new MtRoomInfoReturnVo();
        mtRoomInfoReturnVo.setRoomName(returnRoomName);
        mtRoomInfoReturnVo.setRealRoomId(returnRealRoomId);
        return mtRoomInfoReturnVo;
    }
    /**
     * 方案3.产品接口 产品realRoomid为空，匹配方案2失败是，直接将falseRoomid对比酒店详情接口进行匹配 （60%）
     */
    public String findRealRoomIdByGoodsFalseRoomIdRealIsNull(MtHotelDetailVo vo, String thisMtHotelId, List<MtHotelGoodsBaseRoomVo> goodsBaseRoom){
        String goodsApiReturnRoomIdTrueOrFalse = goodsBaseRoom.get(0).getRoomId();//产品的逻辑物理房型id,roomid   realRoomId为空
        String returnRealRoomId = null;
        List<MtHotelDetailRoomInfoVo> roomRealVoList = vo.getRoomInfos();//酒店详情返回的物理房型信息（逻辑id+物理id）
        if(null != roomRealVoList && roomRealVoList.size()>0) {
            for (MtHotelDetailRoomInfoVo roomInfoVo : roomRealVoList) {
                MtHotelDetailBasicRoomRealInfoVo realVo = roomInfoVo.getRoomBaseInfo();
                String thisVoFalseRoomId = realVo.getRoomId();//酒店详情接口返回假的roomId
                String thisVoTrueRoomId = realVo.getRealRoomId();//酒店详情接口返回真的roomId
                if(null != goodsApiReturnRoomIdTrueOrFalse){
                    if(goodsApiReturnRoomIdTrueOrFalse.equals(thisVoFalseRoomId) || goodsApiReturnRoomIdTrueOrFalse.equals(thisVoTrueRoomId)){
                        returnRealRoomId = thisVoTrueRoomId;
                        break;
                    }
                }
            }
            log.info("findRealRoomIdByGoodsFalseRoomIdRealIsNull获取酒店真实房型酒店id={},realidlist={}，goodsBaseRoom={}",thisMtHotelId,GsonUtils.GsonString(roomRealVoList),GsonUtils.GsonString(goodsBaseRoom));
        }
        if(ObjectUtils.isEmpty(returnRealRoomId)){
            log.info("findRealRoomIdByGoodsFalseRoomIdRealIsNull获取酒店真实房型酒店id={},result={},thisRealRoomId={}，goodsBaseRoom={}",thisMtHotelId,GsonUtils.GsonString(vo),returnRealRoomId,GsonUtils.GsonString(goodsBaseRoom));
        }else{
            log.info("findRealRoomIdByGoodsFalseRoomIdRealIsNull获取酒店真实房型酒店id={},thisRealRoomId={}，goodsBaseRoom={}",thisMtHotelId,returnRealRoomId,GsonUtils.GsonString(goodsBaseRoom));
        }

        return returnRealRoomId;
    }









    /**
     * 美团物理房型接口 比对goodsid 获取到该goodsid所属真实物理房型信息
     * @param mtHotelId
     * @param goodsId
     * @return
     */
    @Override
    public Result<MtHotelRoomDto> getMtHotelRoomCompareGoodId(List<MtHotelRealRoomVo> oneHotelRooms,String mtHotelId,String goodsId) {
        List<Long> hotelIds = new ArrayList<>();
        hotelIds.add(Long.valueOf(mtHotelId));
        if(null != oneHotelRooms && oneHotelRooms.size()>0){
            for (MtHotelRealRoomVo roomVo:oneHotelRooms){
                List<Integer> thisRoomGoodsIds = roomVo.getGoodsIds();
                if(null != thisRoomGoodsIds && thisRoomGoodsIds.size()>0){
                    for (Integer thisGid:thisRoomGoodsIds){
                        if(String.valueOf(thisGid).equals(goodsId)){
                            String thisRoomId = String.valueOf(roomVo.getRealRoomBaseInfo().getRealRoomId());
                            MtHotelRealRoomBaseInfoVo baseInfoVo = roomVo.getRealRoomBaseInfo();
                            MtHotelRoomDto dto = new MtHotelRoomDto();
                            dto.setMtHotelId(mtHotelId);
                            dto.setMtRoomId(thisRoomId);
                            dto.setMtCapacity(baseInfoVo.getCapacity());
                            dto.setMtExtraBed(baseInfoVo.getExtraBed());
                            dto.setMtFloor(baseInfoVo.getFloor());
                            dto.setMtInternetWay(baseInfoVo.getInternetWay());
                            dto.setMtRoomDesc(baseInfoVo.getRoomDesc());
                            dto.setMtRoomName(baseInfoVo.getRoomName());
                            dto.setMtRoomType(baseInfoVo.getRoomType());
                            dto.setMtStatus(String.valueOf(baseInfoVo.getStatus()));
                            dto.setMtUseableArea(baseInfoVo.getUseableArea());
                            dto.setMtWindow(baseInfoVo.getWindow());
                            String windowBad = baseInfoVo.getWindowBad();//再次判断不然存值异常
                            if(!StringUtils.isEmpty(windowBad) && !windowBad.equals("[]")){//第三方问题空值时返回 windowBad": "[]"
                                try{
                                    dto.setMtWindowBad(Integer.valueOf(windowBad));//上游有时候返回数组有时候发返回字符串  [4] 4
                                }catch (Exception e){
                                    List<Integer> win = JSON.parseArray(windowBad,Integer.class);
                                    dto.setMtWindowBad(win.get(0));
                                }
                            }
                            dto.setMtWindowView(baseInfoVo.getWindowView());
                            return new Result<>(dto,"success");
                        }
                    }

                }
            }
        }
        return new Result<>("未发现roomid信息",CommonConstants.SUCCESS);

    }

    /**
     * 直连美团接口-请求获取物理房型数据  支持一次20家酒店
     * @param hotelIds 酒店ids
     * @desc
     */
    @Override
    public Result<Object> getMtHotelRoom(List<Long> hotelIds) {
        //业务参数
        String data = "";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("hotelIds",hotelIds);
        data = JSON.toJSONString(dataMap);
        //发起请求
        String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_ROOM.getMethod(),null);
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        if("0".equals(String.valueOf(responseJson.get("code")))){
            String result = responseJson.getString("result");
            if(null != result){//
                MtHotelRoomVo mtHotelRoomVo = null;
                try {
                    mtHotelRoomVo = JSON.parseObject(result, MtHotelRoomVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(null == mtHotelRoomVo){
                    log.error("////////////////MTAPIERROR///////////////////酒店物理房型接口数据异常 result parse vo error");
                    return new Result<>("parse error",CommonConstants.PARSE_ERROR);
                }else{
                    return new Result<>(mtHotelRoomVo.getRealRoomInfos());
                }

            }else{
                //物理房型数据可能为空
                return new Result<>();
            }
        }else{
            return new Result<>(responseJson.getString("message"),CommonConstants.REQUEST_ERROR);
        }
    }

    /**
     * 最多20个酒店id，获取酒店详情-房型接口需要
     * @param hotelIds
     * @return
     */
    @Override
    public List<MtHotelDetailVo>  returnHotelDetailRoomList(List<Long> hotelIds){
        Result<Object> result = mtHotelService.getMtHotelDetail(hotelIds,null);
        if(null != result && result.getCode() == CommonConstants.SUCCESS){
            if(null != result.getData()){
                List<MtHotelDetailVo> voList = (List<MtHotelDetailVo>)result.getData();
                return voList;
            }
        }
        return null;
    }

    /**
     * 最多20个酒店id，获取酒店详情-房型接口需要
     * @param hotelIds
     * @return
     */
    @Override
    public Map<Long, MtHotelDetailVo>  returnHotelDetailsMap(List<Long> hotelIds){
        Map<Long, MtHotelDetailVo> map = new HashMap<>();
        Result<Object> result = mtHotelService.getMtHotelDetail(hotelIds,null);
        if(null != result && result.getCode() == CommonConstants.SUCCESS){
            if(null != result.getData()){
                List<MtHotelDetailVo> voList = (List<MtHotelDetailVo>)result.getData();
                for (MtHotelDetailVo d:voList){
                    map.put(d.getBaseInfo().getHotelId(),d);
                }
                return map;
            }
        }
        return null;
    }

    /**
     * 最多20个酒店id，获取酒店详情-房型接口需要
     * @param hotelId
     * @return
     */
    @Override
    public MtHotelDetailVo returnHotelDetailRoomListByOneHotelId(String hotelId){
        List<Long> hotelIds = new ArrayList<>();
        hotelIds.add(Long.valueOf(hotelId));
        Result<Object> result = mtHotelService.getMtHotelDetail(hotelIds,null);
        if(null != result && result.getCode() == CommonConstants.SUCCESS){
            if(null != result.getData()){
                List<MtHotelDetailVo> voList = (List<MtHotelDetailVo>)result.getData();
                return voList.get(0);
            }
        }
        return null;
    }



}
